/**
 * 安卓白金英雄坛制作组<br>
 * 文件名：Npc.java<br>
 * 创建时间：2013-7-23 上午11:14:02<br>
 * 所属项目：GmudEX<br>
 *
 * @author 12548
 */
package lostland.gmud.exv2.data;

import android.graphics.Point;
import android.util.SparseArray;
import android.util.SparseIntArray;

import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.Arrays;

import lostland.gmud.exv2.Game;
import lostland.gmud.exv2.GameConstants;
import lostland.gmud.exv2.Gmud;
import lostland.gmud.exv2.MapTile;
import lostland.gmud.exv2.blgframework.Sound;

/**
 * 类名：Npc <br>
 * 说明：非玩家角色
 *
 * @author 12548
 */
public class Npc {

	public static final int FLAG_TEACHER = 1; // 可直接请教的

	public static final int FLAG_MASTER = 2; // 须拜师后才能请教的
	public static final int FLAG_BADMAN = 4; // 除恶任务刷出的NPC
	public static final int FLAG_BOSS = 8; // 东方求败等人
	public static final int FLAG_IMPORTANT = 16; // 重要npc，不能被杀死
	public static final int FLAG_GRANDET = 32; // 葛朗台专用
	public static final int FLAG_UNFIGHTABLE = 64; // 无法战斗 / 已复活过
	public static final int FLAG_UNWATCHABLE = 128; // 无法查看
	public static final int FLAG_SPOUSE = 256; // 结婚配偶
	public static final int FLAG_NODROP = 512; // 战胜不获得物品
	public static final int FLAG_DISAPPEAR_AFTER_DIE = 1024; //死亡后消失
	public static final int FLAG_NICEGUY = 4096; // 除善任务刷出的NPC


	public Point imgindex = new Point(0, 0);
	public int id;                 // id
	public String name = "无名氏";       // 名字

	public int faction = 0;         // 阵营
	public int sex = 0;              // 性别
	public int age = 14;              // 年龄
	public int fame = 0;            // 声望

	public String des = "";          // 描述
	public int exp = 0;              // 经验
	public int ads = 0;             // 加力

	public int hit = 0;                // 命中

	public int evd = 0;              // 闪避

	public int atk = 0;              // 攻击

	public int def = 0;               // 防御

	public int str = 20;             // 膂力

	public int agi = 20;            // 敏捷

	public int wxg = 20;            // 悟性
	public int bon = 20;            // 根骨

	public int maxfp = 100;       // 内力上限

	public int maxfp_bouns = 0;       // 额外的内力上限（海外仙丹）
	public int maxhp_bouns = 0;       //额外的血量


	public int gold = 0;          // 金钱

	public int trigger4 = -1; // 拜师触发


	// SparseIntArray skills = new SparseIntArray();
	public int skills[] = new int[64];       // 技能等级（所有技能）
	public ArrayList<Item> inventory = new ArrayList<>();
	/**
	 * 已装备的技能(拳脚,兵刃,轻功,内功,招架,暗器)<br>
	 * 未装备为-1
	 */
	public int skillsckd[] = {-1, -1, -1, -1, -1, -1};
	/**
	 * 已装备的物品(通常第一为武器，第二开始为防具)<br>
	 * 未装备为0
	 */
	public Item equipments[] = new Item[20]; // 勾选物品
	// 与旧版json兼容
//	public int items[];
//	public int itemsckd[];
	public int trading;      // 交易列表id
	public int sells[] = new int[0];
	public String title = "";// 称号
	public int talent = -1; // 天赋


	public ArrayList<String> saying = new ArrayList<>();

	/**
	 * NPC特殊功能指示符，二进制整数，可根据位运算规律叠加
	 */
	public int flag = 0;

	public boolean qingjiaoable = false; // 可请教

	private int sp;       // 体力

	private int hp;       // 生命

	// ///////////////////////////////////////////////////////////////////////

	protected int fp;       // 内力

	public SparseIntArray extraAttr = new SparseIntArray();
	public SparseArray<Float> extraAttrRate = new SparseArray<>();
	public SparseArray<Sound> voices = new SparseArray<>();

	private NpcBattleData data = null;

	public Npc() {

//		for (int i = 0; i < equipments.length; i++) {
//			if (equipments[i] == null) {
//				equipments[i] = Item.getNullItem();
//			}
//		}
	}

	public Npc add(int value) {
		ads = value;
		return this;
	}

	/**
	 * 增减怒气值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要增加的怒气值
	 */
	public void addGauge(int value) {
		getBattleData().gauge += value;
		getBattleData().gauge = Gmud.format(getBattleData().gauge, 0, GameConstants.GAUGE_MAX);
	}

	public Npc age(int value) {
		age = value;
		return this;
	}


	// ///////////////////////////////////////////////////////////////////////


	public Npc agility(int value) {
		agi = value;
		return this;
	}

	public boolean alive() {
		return !Game.getInstance().data.death_note.contains(id);
	}

	/**
	 * 追杀目标生成
	 *
	 * @param bad 是否为坏人
	 */
	public void badman(boolean bad) {
		str = (sex == 0) ? 24 : 14;
		agi = (sex == 0) ? 18 : 32;
		wxg = (sex == 0) ? 22 : 30;
		bon = (sex == 0) ? 26 : 14;

		int skl[][] = {
				{},
				{0, 1, 7, 8, 3, 15, 11, 13, 14},
				{0, 1, 7, 8, 2, 33, 30, 31, 32},
				{0, 1, 7, 8, 6, 16, 17, 19, 20}, // female
				{0, 1, 7, 8, 3, 28, 29, 27, 26},
				{0, 1, 7, 8, 5, 21, 23, 24, 25},
				{0, 1, 7, 8, 2, 35, 38, 39, 36}
		};
		if (!bad) {
			skl[1][7] = 12;
			skl[2][6] = 34;
			skl[3][6] = 18;
			skl[6][6] = 37;
		}// 好人模式，更换技能
		if (sex == 0) {
			skl[3] = skl[4];
			// 男人不能是花间派
		}

		exp = Gmud.mc.exp;

		skills = new int[Gmud.skill.length];
		Arrays.fill(skills, 0);

		int s = 0;

		for (int i : Gmud.mc.skills) {
			if (i > s) {
				s = i;
			}
		}

		int a = s;

		if (!bad) {
			a *= 1.2f; // 增加除善难度
		}

//		for (int b : skl[faction]) {
//			skills[b] = a;
//		}

		int ckd[][] = {
				{},
				{13, 11, 15, 14, 11}, // 八卦
				{31, 30, 33, 32, 30}, // 太极
				{19, 17, 16, 20, 17}, // 花间
				{27, 29, 28, 26, 29}, // 尹贺
				{24, 23, 21, 25, 23}, // 红莲
				{39, 38, 35, 36, 38}  // 雪山
		};
		if (!bad) {
			ckd[1][0] = 12;
			ckd[2][1] = 34;
			ckd[2][4] = 34;
			ckd[3][1] = 18;
			ckd[3][4] = 18;
			ckd[6][1] = 37;
			ckd[6][4] = 37;
		}
		if (sex == 0) {
			ckd[3] = ckd[4];
		}

//		skillsckd = ckd[faction];

		maxfp = getMaxfpLimit();
//		maxhp = getMaxhpInTheory();

		ads = skillsckd[3] / 2 + skills[Skill.KIND_NEIGONG] / 4;

		gold = 100;
	}

	public Gesture cag(int wg) {
		int t = chooseAGesture(wg);
		Logger.w("" + t);
		return Gmud.zs.get(t);
	}

	/**
	 * NPC携带物品
	 *
	 * @param item 物品id
	 * @return NPC自己
	 */
	public Npc carry(int item) {
		give(item);
		return this;
	}

	/**
	 * NPC携带并装备物品
	 *
	 * @param item 物品id
	 * @return NPC自己
	 */
	public Npc carryandequip(int item) {
		equip(give(item));
		return this;
	}

	public Gesture cg() {
		return cag(getAttackSkill().id);
	}

	/**
	 * 获得随机招式（轻功、招架除外）
	 *
	 * @param wg 技能ID
	 */
	public int chooseAGesture(int wg) {
		int l = skills[wg];
		Skill t = Gmud.skill[wg];
		int i = t.zse;

		while (Gmud.zs.get(i).llimit > l) {
			i--;
		}

		int s = i - t.zss + 1;

		return t.zss + Gmud.rand.nextInt(s);
	}

	public Npc constitution(int value) {
		bon = value;
		return this;
	}

	public void copy(int index) {
		copy(Gmud.getNpc(index));
	}


	/**
	 * 全属性复制
	 *
	 * @param other 目标NPC
	 */
	public void copy(Npc other) {
		maxfp = other.maxfp;
//		maxhp = other.maxhp;

		str = other.str;
		agi = other.agi;
		bon = other.bon;
		wxg = other.wxg;

		hit = other.hit;
		evd = other.evd;
		atk = other.atk;
		def = other.def;

		setExp(other.exp);

		ads = other.ads;

		skills = other.skills.clone();
		skillsckd = other.skillsckd.clone();

		inventory = (ArrayList<Item>) other.inventory.clone();
		equipments = other.equipments.clone();

		refresh();
	}

	/**
	 * 拷贝某一NPC的技能
	 *
	 * @param npcid 目标
	 */
	public Npc copy_skills(int npcid) {
		skills = Gmud.getNpc(npcid).skills.clone();
		skillsckd = Gmud.getNpc(npcid).skillsckd.clone();
		return this;
	}

	/**
	 * 获取出手等级
	 */
	public int cs() {
		int t = ads / 2 + getAttr(Room.ATTR_STR);
		if (getAttackItem().getKind() == 2) {
			t += getAttackItem().getA3();
		}

//		Logger.i("出手等级为" + t);
		return t;
	}


	/**
	 * 治愈
	 *
	 * @param val 值
	 */
	public void cure(int val) {
		setHp(getHp() + val);
		if(getHp() > getAttr(Room.ATTR_MAXHP)) {
			setHp(getAttr(Room.ATTR_MAXHP));
		}
	}

	public void delFlag(int flag) {
		if (haveFlag(flag)) {
			this.flag -= flag;
		}
	}


	public boolean disappeared() {
		return Game.getInstance().data.vanish_note.contains(id);
	}

	/**
	 * 体力伤害
	 *
	 * @param dmg 伤害值
	 * @param fix 受伤修正
	 */
	public void dmg(int dmg, int fix) {
		dmg *= getTemp_dmg_multiplier();
		setTemp_dmg_multiplier(1.0);

// if(this == Gmud.mc && age > 50)
// dmg *= 3;

		setSp(getSp() - dmg);
		if(getSp() < 0) {
			setSp(0);
		}

		Logger.w("" + dmg);
	}

	/**
	 * 生命伤害
	 *
	 * @param dmg    值
	 * @param fix    受伤修正
	 * @param sender 攻击方
	 */
	public void dmg(int dmg, int fix, Npc sender) {
		Logger.w("" + dmg);
		dmg *= getTemp_dmg_multiplier();
		setTemp_dmg_multiplier(1.0);
		Logger.w("" + dmg);

		if(sender.haveTalent(2077) && this.fame < ((this instanceof MainChar) ? 128 : 0)) {
			dmg *= 1.2;
		}

// if(sender == Gmud.mc && sender.age > 50)
// dmg /= 3;

		if (skillsckd[4] == 43) {
			int fpn = (int) ((1.0 / (skills[43] * 0.005 + 1.495)) * dmg * 0.5);
			if (fpn < 1) {
				fpn = 1;
			}
			if (getFp() > fpn) {
				setFp(getFp() - fpn);
				dmg *= 0.5;
				getBattleData().hurtpf += "【金钟罩】";
			}

			Logger.w("" + dmg);
		}

		int dd = sender.cs() + fix - getAttr(Room.ATTR_DEF) - getAttr(Room.ATTR_BON) / 2;

		if(isImmuHpDmg()) // 天赋效果1013
		{
			dd = 0;
			dmg -= 25;
			getBattleData().hurtpf += "【金刚不坏】";
		}

		if (dd < 0) {
			dd = 0;
		}
		if (dmg < dd) {
			dmg = dd;
		}

		if (haveTalent(30) && haveFlag(32768)) {
			// 天赋 开卷有益
			dmg /= 2;
			dd /= 2;
			delFlag(32768);
		}

		setSp(getSp() - dmg);
		if(getSp() < 0) {
			setSp(0);
		}

		setHp(getHp() - dd);
		if(getHp() < 0) {
			setHp(0);
		}

		Logger.w("" + dmg);
		Logger.w("" + dd);

	}


	/**
	 * @return 是否免疫受伤
	 */
	public boolean isImmuHpDmg() {
		return haveTalent(1013);
	}

	public void draw(int x, int y) {
		draw(x, y, 0, 0);
	}


	public void draw(int x, int y, int dx, int dy) {
		if (!alive()) {
			MapTile.getInstance().draw(x, y, 15, 15, dx, dy);
		} else if (!disappeared()) {
			MapTile.getInstance().draw(x, y, imgindex.x, imgindex.y + 1, dx, dy);
		}
	}


	public void drawInMap(int x, int y) {
		drawInMap(x, y, 0, 0);
	}

	public void drawInMap(int x, int y, int dx, int dy) {
		if (!alive()) {
			MapTile.getInstance().drawInMap(x, y, 15, 15, dx, dy);
		} else if (!disappeared()) {
			MapTile.getInstance().drawInMap(x, y, imgindex.x, imgindex.y + 1, dx, dy);
		}
	}

	/**
	 * 装备武器或防具<br>
	 *
	 * @param item 物品
	 */
	public Npc equip(Item item) {
		if (item == null)
			return this;
		if (equips(item)) {
			unequip(item);
			return this;
		}

		if (item.getKind() == 2) {
			for (int i = 0; i < equipments.length; i++) {
				if (equipments[i] == null || equipments[i].getKind() == 2) {
					equipments[i] = Item.getNullItem();
				}
			}
		}

		equipments[item.getSubkind()] = item;
		return this;
	}

	/**
	 * 是否装备了武器/防具
	 *
	 * @param weapon 武器true 防具false
	 */
	public boolean equips(boolean weapon) {
		//
		for (Item i : equipments) {
			if (i.getKind() == 2 && !i.equals(Item.getNullItem()) && weapon)
				return true;
			if (i.getKind() == 3 && !weapon)
				return true;
		}
		return false;
	}

	/**
	 * 是否装备某件物品
	 *
	 * @param itmid 物品ID
	 * @return 是否装备
	 */
	public boolean equips(int itmid) {
		for (Item i : equipments) {
			if (i == null) {
				i = Item.getNullItem();
			}
			if (itmid == i.getId())
				return true;
		}
		return false;
	}

	/**
	 * 是否装备某件物品
	 *
	 * @param item 物品
	 * @return 是否装备
	 */
	public boolean equips(Item item) {
		if (item == null) return false;
		for (Item i : equipments) {
			if (i == null) {
				i = Item.getNullItem();
			}
			if (item.equals(i))
				return true;
		}
		return false;
	}

	public Npc exp(int value) {
		exp = value;
		return this;
	}

	/**
	 * 是否还有足够的经验去学习
	 *
	 * @param lv 目标等级（当前等级+1）
	 */
	public boolean expcanlearn(int lv) {
		return lv * lv * lv * 0.1 - lv * lv * 0.2 + lv * 0.4 - 2 < exp;
	}

	public Item findItem(int itmid) {
		for (Item i : inventory)
			if (i.getId() == itmid)
				return i;
		return Item.getNullItem();
	}

	public Npc flag(int flag) {
		this.flag |= flag;
		return this;
	}

	public Npc fp(int value) {
		setFp(value);
		maxfp = value;
		return this;
	}

	public Npc gender(int value) {
		sex = value;
		return this;
	}

	/**
	 * 获取加力上限
	 */
	public int getAdsLimit() {
		int x;

		if (skillsckd[3] < 10) {
			x = 0;
		} else {
			x = skills[Skill.KIND_NEIGONG] / 4 + skills[skillsckd[3]] / 2;
		}

		if (haveTalent(1005)) {
			x *= 2; // 天赋效果1005
		}

		return x;
	}

	public int getAgi() {
		return agi + skills[Skill.KIND_QINGGONG] / 10 + getAgi_bouns() + getRuneValue(0, 1);
	}

	/**
	 * 获取战场敏捷加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场敏捷加值
	 */
	public int getAgi_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().agi_bouns;
	}

	public int getAtk() {
		int t = 0;
		for(Item equipment : equipments) {
			if(equipment.getKind() == 2) {
				t += equipment.getA3();
			}
		}
		return atk + t + getAtk_bouns();
	}

	/**
	 * 获取战场攻击加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场攻击加值
	 */
	public int getAtk_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().atk_bouns;
	}

	public Item getAttackItem() {
		for (Item i : equipments) {
			if (Item.notNull(i))
				if (i.getKind() == 2)
					return i;
		}
		return Item.getNullItem();
	}

	/**
	 * 获取攻击技能
	 */
	public Skill getAttackSkill() {

		if (getAttackItem().getKind() == 2)
			if (getAttackItem().getSubkind() == 11) {
				if (skillsckd[0] > -1) {
					Logger.i(Gmud.skill[skillsckd[0]].name);
					return Gmud.skill[skillsckd[0]];
				} else {
					Logger.i(Gmud.skill[Skill.KIND_QUANJIAO].name);
					return Gmud.skill[Skill.KIND_QUANJIAO];
				}
			} else if (skillsckd[1] > -1
					&& Gmud.skill[Skill.eqpbias2[getAttackItem().getSubkind()]].subkind == Gmud.skill[skillsckd[1]].subkind) {
				Logger.i(Gmud.skill[skillsckd[1]].name);
				return Gmud.skill[skillsckd[1]];
			} else {
				Logger.i(Gmud.skill[Skill.eqpbias2[getAttackItem()
						.getSubkind()]].name);
				return Gmud.skill[Skill.eqpbias2[getAttackItem().getSubkind()]];
			}
		else if (skillsckd[0] > -1) {
			Logger.i(Gmud.skill[skillsckd[0]].name);
			return Gmud.skill[skillsckd[0]];
		} else {
			Logger.i(Gmud.skill[Skill.KIND_QUANJIAO].name);
			return Gmud.skill[Skill.KIND_QUANJIAO];
		}

	}

	public int getAttr(int id) {
		int t = 0;
		int x = this instanceof MainChar ? 0 : Game.getInstance().data.getSyuume();
		switch (id) {
			case Room.ATTR_ADS:
				t = ads;
				break;
			case Room.ATTR_AGI:
				t = getAgi() + x;
				break;
			case Room.ATTR_ATK:
				t = getAtk();
				break;
			case Room.ATTR_BON:
				t = getBon() + x;
				break;
			case Room.ATTR_CRIT:
				t = 0;
				break;
			case Room.ATTR_DEF:
				t = getDef();
				break;
			case Room.ATTR_EVD:
				t = getEvd();
				break;
			case Room.ATTR_EXP:
				t = exp + x * 4000;
				break;
			case Room.ATTR_HIT:
				t = getHit();
				break;
			case Room.ATTR_MAXFP:
				t = maxfp + getRuneValue(2, 1);
				break;
			case Room.ATTR_MAXHP:
				t = getMaxhpInTheory() + getRuneValue(2, 0) + maxhp_bouns;
				break;
			case Room.ATTR_MULTI:
				t = 0;
				break;
			case Room.ATTR_SPSTEAL:
				t = 0;
				break;
			case Room.ATTR_STR:
				t = getStr() + x;
				break;
			case Room.ATTR_WXG:
				t = getWxg() + x;
				break;
			case Room.ATTR_GENDER:
				return sex;
			case Room.ATTR_FACTION:
				return faction;
		}

// t += extraAttr.get(id);
// t *= 1f + extraAttrRate.get(id, 0f);

		return t;
	}

	public double getBattleBLK() {
		double t = getWC() + getAttr(Room.ATTR_AGI) + getAttr(Room.ATTR_STR)
				+ getAttr(Room.ATTR_BON) + skills[Skill.KIND_ZHAOJIA];
		if (getAttackSkill().id > 9) {
			t += skills[getAttackSkill().id] * 2.0 / 3.0;
		}

		if (getAttackItem().equals(Item.getNullItem())) {
			t *= 0.5;
		}

		Logger.w("战场格挡=" + t);
		return t;
	}

	public double getBattleEvd() {
		double t = getWC() + getAttr(Room.ATTR_AGI) * 2
				+ skills[getEquipedSkill(2).getBasicSkill().id] / 3.0;
		if (getEquipedSkill(2).id > 9) {
			t += skills[getEquipedSkill(2).id] * 2.0 / 3.0;
		}
		t *= Gmud.format(Gmud.mc.getAttr(Room.ATTR_EVD), -255, 255) * (1.0 / 256.0) + 1.0;
		Logger.w("战场回避=" + t);
		return t;
	}


	public double getBattleHit(Skill attackSkill) {
		Logger.w("正在获取战场命中");

		if (attackSkill == null) {
			attackSkill = getAttackSkill();
		}

		double t = 0;
		t += getWC();
		t += getAttr(Room.ATTR_STR) * 2;
		if (attackSkill.id > 9) {
			t += skills[attackSkill.id] * 2.0 / 3.0;
		}
		t += skills[attackSkill.getBasicSkill().id] / 3.0;
		t *= Gmud.format(Gmud.mc.getAttr(Room.ATTR_HIT), -255, 255) * (1.0 / 256.0) + 1.0;
		Logger.w("战场命中=" + t);
		return t;
	}

	public int getBon() {
		return bon + skills[Skill.KIND_NEIGONG] / 10 + getBon_bouns() + getRuneValue(0, 3);
	}

	/**
	 * 获取战场根骨加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场根骨加值
	 */
	public int getBon_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().bon_bouns;
	}


	/**
	 * 获取指定状态的剩余持续回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param index 指定的状态编号
	 * @return 该状态的剩余持续回合数
	 */
	public int getBuff(int index) {
		if (getBattleData() == null)
			return 0;
		return getBattleData().buff.get(index);
	}

	/**
	 * 获取出手描述
	 */
	public String getcs() {

		String s[] = new String[]{"极轻", "很轻", "不轻", "不重", "很重", "极重"};

		int t = cs();

		if (t < 20)
			return s[0];
		else if (t < 40)
			return s[1];
		else if (t < 60)
			return s[2];
		else if (t < 80)
			return s[3];
		else if (t < 100)
			return s[4];
		else
			return s[5];
	}

	/**
	 * 获取防御值
	 *
	 * @return 防御
	 */
	public int getDef() {
		int t = 0;
		for (Item i : equipments) {
			if (i.getKind() == 3) {
				t += i.getA3();
			}
		}
		return def + t + getDef_bouns();
	}


	/**
	 * 获取战场防御加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场防御加值
	 */
	public int getDef_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().def_bouns;
	}


	/**
	 * 获取NPC的剩余金创药数目<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的剩余金创药数目
	 */
	public int getDrug1() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().drug1;
	}

	/**
	 * 获取NPC的剩余生肌膏数目<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的剩余生肌膏数目
	 */
	public int getDrug2() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().drug2;
	}

	/**
	 * 获取角色的剩余呆若木鸡回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的剩余呆若木鸡回合数
	 */
	public int getDz() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().dz;
	}

	/**
	 * 获得指定类型的装备技能（不适用于兵刃）
	 *
	 * @param eqpkind 装备技能类型（0拳脚1兵刃2轻功3内功4招架）
	 * @return Skill
	 */
	public Skill getEquipedSkill(int eqpkind) {
		return (skillsckd[eqpkind] > -1) ? Gmud.skill[skillsckd[eqpkind]] : Gmud.skill[Skill.kind_basic_skills[eqpkind]];
	}

	public int getEvd() {
		int t = 0;
		for (Item i : equipments) {
			if (i.getKind() == 2 || i.getKind() == 3) {
				t += i.getA5();
			}
		}
		return evd + t + getEvd_bouns() + getRuneValue(2, 3);
	}

	/**
	 * 获取战场闪避加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场闪避加值
	 */
	public int getEvd_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().evd_bouns;
	}

	/**
	 * 获取怒气值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的怒气值
	 */
	public int getGauge() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().gauge;
	}

	public int getHit() {
		int t = 0;
		for (Item i : equipments) {
			if (i.getKind() == 2 || i.getKind() == 3) {
				t += i.getA4();
			}
		}
		return hit + t + getHit_bouns() + getRuneValue(2, 2);
	}

	/**
	 * 获取战场命中加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场命中加值
	 */
	public int getHit_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().hit_bouns;
	}

	public int getMaxfpLimit() {
		if (skillsckd[3] == -1) return 0;
		int agee = Math.min(age, 60);
		int fp = exp / 1000 + skills[Skill.KIND_NEIGONG] * 5 + skills[skillsckd[3]] * 10
				+ (agee - 14) * 20 + maxfp_bouns;
		return Math.min(fp, GameConstants.FP_LIMIT);
	}

	public int getMaxhpInTheory() {
		int age = Gmud.format(this.age, 14, 29);
		return (age - 14) * 20 + 100 + maxfp / 4;
	}

	/**
	 * 获取新实力评价
	 */
	public int getNewpj() {
		return getWC() + getpj() * 20 + getAttr(Room.ATTR_MAXFP) / 40 + getMaxhp() / 10;
	}

	/**
	 * 获取评价
	 */
	public int getpj() {
		int t = skills[Skill.KIND_ZHAOJIA] + skills[Skill.KIND_QINGGONG];
		if (getEquipedSkill(2).id > 10) {
			t += skills[getEquipedSkill(2).id] * 2;
		}

		if (getAttackItem().getKind() == Skill.KIND_BINGREN && getAttackItem().getSubkind() != 11) {
			t += skills[getEquipedSkill(1).getBasicSkill().id] * 2;
			if (skillsckd[1] > -1
					&& Gmud.skill[Skill.eqpbias2[getAttackItem().getSubkind()]].subkind == Gmud.skill[skillsckd[1]].subkind) {
				t += skills[skillsckd[1]] * 4;
			}

			if (skillsckd[1] == skillsckd[4] && skillsckd[4] > -1) {
				t += skills[skillsckd[4]] * 2;
			}
		} else {
			t += skills[getEquipedSkill(0).getBasicSkill().id] * 2;
			if (skillsckd[0] > -1) {
				t += skills[skillsckd[0]] * 4;
			}

			if (skillsckd[0] == skillsckd[4] && skillsckd[4] > -1) {
				t += skills[skillsckd[4]] * 2;
			}
		}

//		Logger.i("总评等级为" + t / 12);

		return t / 60;
	}

	public String getRunePrefix(int a0, int a1) {
		String t = "";
		for (Item i : equipments) {
			t += i.getRuneName(a0, a1);
		}
		return t;
	}

	public int getRuneValue(int a0, int a1) {
		int t = 0;
		for (Item i : equipments)
			if (Item.notNull(i)) {
				t += i.getRuneValue(a0, a1);
			}
		return t;
	}

	/**
	 * 获得当前最大或最小等级的技能的等级
	 *
	 * @param getmax 是否获得最大等级
	 */
	public int getSkilllevel(boolean getmax) {
		int n = getmax ? 0 : 260;
		for (int i : skills)
			if ((getmax && n < i) || (!getmax && n > i)) {
				n = i;
			}
		return n;
	}

	public int getStr() {
		return str + skills[Skill.KIND_QUANJIAO] / 10 + getStr_bouns() + getRuneValue(0, 0);
	}

	/**
	 * 获取战场膂力加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场膂力加值
	 */
	public int getStr_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().str_bouns;
	}

	/**
	 * 获取指定绝招的剩余收招回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param index 指定的绝招编号
	 * @return 该绝招的剩余收招回合数
	 */
	public int getSz(int index) {
		if (getBattleData() == null)
			return 0;
		return getBattleData().sz.get(index);
	}

	/**
	 * 获取临时伤害倍率<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的临时伤害倍率
	 */
	public double getTemp_dmg_multiplier() {
		if (getBattleData() == null)
			return 1.0;
		return getBattleData().temp_dmg_multiplier;
	}

	/**
	 * 获取武学常识，即额外属性的修正参数
	 */
	public int getWC() {
		double t = 0.0d;
		for(int skill : skills) {
			t += skill;
		}
		t *= 0.1;

		t += getAttr(Room.ATTR_EXP) / 400.0;


		Logger.w("武常=" + t);
		return Gmud.format((int) t, -1, 1000 * (Game.getInstance().data.getSyuume() + 1));
	}

	public int getWxg() {
		return wxg + skills[Skill.KIND_ZHISHI] / 10 + getWxg_bouns() + getRuneValue(0, 2);
	}

	/**
	 * 获取战场悟性加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @return 要获取的战场悟性加值
	 */
	public int getWxg_bouns() {
		if (getBattleData() == null)
			return 0;
		return getBattleData().wxg_bouns;
	}

	/**
	 * NPC获得物品，注意这里每样物品只能获得一件
	 *
	 * @param index 物品ID
	 * @return 所给出的物品。如果失败则返回Item.NullItem。
	 */
	public Item give(int index) {
		if (this instanceof MainChar) {
			if (!give(Item.generateItem(index, -1))) return Item.getNullItem();
			return findItem(index);
		}
		if (this.have(index)) return findItem(index);
		final Item item = Item.generateItem(index, -1);
		if (!give(item)) return Item.getNullItem();
		return item;
	}

	/**
	 * NPC获得物品，注意这里每样物品只能获得一件(主要作用为扩展items数组)
	 *
	 * @param item 物品
	 * @return 是否成功
	 */
	public boolean give(Item item) {
		if (this.have(item)) return false;
		inventory.add(item);
		return true;
	}

	public Npc gold(int value) {
		gold = value;
		return this;
	}


	/**
	 * 是否拥有物品(注意这里只要模板相同即算拥有)
	 *
	 * @param index 物品id
	 */
	public boolean have(int index) {
		for (Item i : inventory)
			if (i.getId() == index)
				return true;
		return false;
	}

	/**
	 * 是否拥有物品
	 *
	 * @param itm 物品
	 */
	public boolean have(Item itm) {
		return inventory.contains(itm);
	}

	public boolean haveFlag(int flag) {
		return (this.flag & flag) > 0;
	}


	/**
	 * 是否拥有某个天赋，以后可以扩展成multi-talent
	 *
	 * @param talent 天赋id
	 * @see Gmud#talent_desc
	 */
	public boolean haveTalent(int talent) {
		return this.talent == talent;
	}

	public boolean haveTalent(String talentName) {
		for (int i = 0; i < Gmud.getTalent_desc().size(); i++) {
			if (Gmud.getTalent_desc().valueAt(i).getName().equals(talentName))
				return haveTalent(Gmud.getTalent_desc().keyAt(i));
		}
		return false;
	}

	public Npc intelligence(int value) {
		wxg = value;
		return this;
	}

	public Npc introduction(String s) {
		des = s;
		return this;
	}

	/**
	 * 当前是否可以使用绝招
	 *
	 * @return stuntAvaliable
	 */
	public boolean isStuntAvaliable() {
		return getBattleData() != null && getBattleData().stuntAvaliable;
	}

	public Npc learn(int id, int level) {
		skills[id] = level;
		return this;
	}

	/**
	 * 技能列表字符串
	 *
	 * @param str 举例：0:200,1:150,20:250,45:20:1<br>
	 *            技能id:技能等级:是否装备
	 */
	public Npc learn(String str) {
		String skillsplit[] = str.split(",");
		for (String s : skillsplit) {
			String splt[] = s.split(":");
			skills[Integer.parseInt(splt[0])] = Integer.parseInt(splt[1]);
			if (splt.length > 2 && splt[2].length() > 0) {
				skillsckd[Gmud.skill[Integer.parseInt(splt[0])].pos] = Integer.parseInt(splt[0]);
			}
		}
		return this;
	}

	public Npc look(int imgx, int imgy) {
		imgindex = new Point(imgx, imgy);
		return this;
	}

	public Npc looklike(int npc) {
		imgindex = Gmud.getNpc(npc).imgindex;
		return this;
	}

	public Npc name(String s) {
		name = s;
		return this;
	}

	/**
	 * 在地图上显示。
	 *
	 * @param map 地图id
	 * @param x   x坐标
	 * @param y   y坐标
	 * @return 返回npc自己本身，以便于继续处理。
	 */
	public Npc place(int map, int x, int y) {
		Gmud.maps[map].npc(x, y, id);
		return this;
	}

	/**
	 * 在地图上显示。
	 *
	 * @param place 地点
	 * @return 返回npc自己本身，以便于继续处理。
	 */
	public Npc place(FlyPoint place) {
		Gmud.maps[place.map].npc(place.x, place.y, id);
		return this;
	}

	/**
	 * 体力恢复
	 *
	 * @param val 值
	 */
	public void rec(int val) {
		setSp(getSp() + val);
		if(getSp() > getHp()) {
			setSp(getHp());
		}
	}

	protected void rectify_equipments() {
		for (int i = 0; i < equipments.length; i++) {
			if (equipments[i] == null) {
				equipments[i] = Item.getNullItem();
			}
		}
	}

	/**
	 * 状态刷新
	 */
	public void refresh() {
		setFp(getAttr(Room.ATTR_MAXFP));
		setHp(getAttr(Room.ATTR_MAXHP));
		setSp(getHp());
		Logger.w("NPC %s is refreshed.", this.name);
	}

	public Npc say(String s) {
		saying.add(s);
		return this;
	}

	public Npc say(String s, Sound snd) {
		saying.add(s);
		voices.append(saying.size() - 1, snd);
		return this;
	}

	public Npc sell(int id) {
		trading = 1;
		sells = Gmud.push_back(sells, id);
		return this;
	}

	/**
	 * 设置战场敏捷加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场敏捷加值
	 */
	public void setAgi_bouns(int value) {
		getBattleData().agi_bouns = value;
	}

	/**
	 * 设置战场攻击加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场攻击加值
	 */
	public void setAtk_bouns(int value) {
		getBattleData().atk_bouns = value;
	}

	public void setAttr(int id, int value) {
		switch (id) {
			case Room.ATTR_ADS:
				ads = value;
				break;
			case Room.ATTR_AGI:
				agi = value;
				break;
			case Room.ATTR_ATK:
				atk = value;
				break;
			case Room.ATTR_BON:
				bon = value;
				break;
			case Room.ATTR_CRIT:

				break;
			case Room.ATTR_DEF:
				def = value;
				break;
			case Room.ATTR_EVD:
				evd = value;
				break;
			case Room.ATTR_EXP:
				exp = value;
				break;
			case Room.ATTR_HIT:
				hit = value;
				break;
			case Room.ATTR_MAXFP:
				maxfp = value;
				break;
			case Room.ATTR_MAXHP:
//				maxhp = value;
				break;
			case Room.ATTR_MULTI:

				break;
			case Room.ATTR_SPSTEAL:

				break;
			case Room.ATTR_STR:
				str = value;
				break;
			case Room.ATTR_WXG:
				wxg = value;
				break;
			case Room.ATTR_GENDER:
				sex = value;
				break;
			case Room.ATTR_FACTION:
				faction = value;
				break;
		}
	}

	/**
	 * 设置战场根骨加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场根骨加值
	 */
	public void setBon_bouns(int value) {
		getBattleData().bon_bouns = value;
	}

	/**
	 * 设置指定状态的剩余持续回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param index 指定的状态编号
	 * @param value 要设置的剩余持续回合数
	 */
	public void setBuff(int index, int value) {
		getBattleData().buff.put(index, value);
	}

	/**
	 * 设置战场防御加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场防御加值
	 */
	public void setDef_bouns(int value) {
		getBattleData().def_bouns = value;
	}

	/**
	 * 调整难度
	 *
	 * @param multiplier 放大倍数
	 */
	public void setDifficulty(float multiplier) {
		str *= multiplier;
		agi *= multiplier;
		wxg *= multiplier;
		bon *= multiplier;

		atk *= multiplier;
		def *= multiplier;
		hit *= multiplier;
		evd *= multiplier;

// this.exp *= multiplier;

		maxfp *= multiplier;
//		maxhp *= multiplier;

		for (int i = 0; i < skills.length; i++) {
			skills[i] *= multiplier;
		}

		refresh();
	}

	/**
	 * 设置NPC的剩余金创药数目<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的剩余金创药数目
	 */
	public void setDrug1(int value) {
		getBattleData().drug1 = value;
	}

	/**
	 * 设置NPC的剩余生肌膏数目<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的剩余生肌膏数目
	 */
	public void setDrug2(int value) {
		getBattleData().drug2 = value;
	}

	/**
	 * 设置角色的剩余呆若木鸡回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param dz 要设置的剩余呆若木鸡回合数
	 */
	public void setDz(int dz) {
		getBattleData().dz = dz;
	}

	/**
	 * 设置战场敏捷加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场闪避加值
	 */
	public void setEvd_bouns(int value) {
		getBattleData().evd_bouns = value;
	}

	/**
	 * @param exp 要设置的经验
	 */
	public void setExp(int exp) {
		this.exp = exp;
		if (this.exp > GameConstants.EXP_LIMIT) {
			this.exp = GameConstants.EXP_LIMIT;
		}
	}

	/**
	 * 设置战场命中加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场命中加值
	 */
	public void setHit_bouns(int value) {
		getBattleData().hit_bouns = value;
	}

	/**
	 * 设置战场膂力加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场膂力加值
	 */
	public void setStr_bouns(int value) {
		getBattleData().str_bouns = value;
	}

	/**
	 * @param stunt 设置是否允许使用绝招
	 */
	public void setStunt(boolean stunt) {
		getBattleData().stuntAvaliable = stunt;
	}

	/**
	 * 设置指定绝招的剩余收招回合数<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param index 指定的绝招编号
	 * @param value 要设置的剩余收招回合数
	 */
	public void setSz(int index, int value) {
		getBattleData().sz.put(index, value);
	}

	/**
	 * @param talent 要设置的天赋
	 */
	public void setTalent(int talent) {
		this.talent = talent;
	}

	/**
	 * 设置临时伤害倍率<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的临时伤害倍率
	 */
	public void setTemp_dmg_multiplier(double value) {
		getBattleData().temp_dmg_multiplier = value;
	}

	/**
	 * @param dz 要设置的呆若木鸡回合数
	 */
	public void setTransfixed(int dz) {
		if (haveTalent(2050)) {
			setDz(0);
		} else {
			setDz(dz);
		}
	}

	/**
	 * 设置战场悟性加值<br>
	 * <i>战斗专用属性</i>
	 *
	 * @param value 要设置的战场悟性加值
	 */
	public void setWxg_bouns(int value) {
		getBattleData().wxg_bouns = value;
	}

	/**
	 * 缩放技能等级
	 *
	 * @param skills 技能表
	 * @param zoom   缩放参数
	 */
	public void setZoomSkill(int skills[], double zoom) {
		for (int sid = 0; sid < skills.length; sid++) {
			this.skills[sid] = (int) (zoom * skills[sid]);
		}
	}

	// 不说话了
	public Npc silent() {
		saying.clear();
		voices.clear();
		return this;
	}

	public Npc strength(int value) {
		str = value;
		return this;
	}

	public Npc talent(int talentid) {
		talent = talentid;
		return this;
	}

	public Npc title(String s) {
		title = s;
		return this;
	}

	/**
	 * 将NPC类型转换为MainChar类型
	 *
	 * @return mc
	 */
	public MainChar toMC() {
		MainChar mc = new MainChar();
		mc.looklike(id);
		mc.name = name;
		mc.saying = saying;
		mc.sex = sex;
		mc.age = age;
		mc.faction = faction;
		mc.talent = talent;
		mc.fame = fame;
		mc.gold = gold;
		mc.sells = sells;
		mc.setEvd_bouns(getEvd_bouns());
		mc.setHit_bouns(getHit_bouns());
		mc.setDef_bouns(getDef_bouns());
		mc.setBon_bouns(getBon_bouns());
		mc.setAtk_bouns(getAtk_bouns());
		mc.setAgi_bouns(getAgi_bouns());
		mc.setStr_bouns(getStr_bouns());
		mc.setWxg_bouns(getWxg_bouns());
		mc.maxfp_bouns = maxfp_bouns;
// mc.ori0 = this.ori0;
		mc.trading = trading;
		mc.qingjiaoable = qingjiaoable;
		mc.copy(this);

		return mc;
	}

	/**
	 * 取消装备物品
	 *
	 * @param item 要取消装备的物品id
	 */
	public void unequip(int item) {
		unequip(findItem(item));
	}

	/**
	 * 取消装备物品
	 *
	 * @param item 要取消装备的物品
	 */
	public void unequip(Item item) {
		if (item.equals(Item.getNullItem()))
			return;
		equipments[item.getSubkind()] = Item.getNullItem();
	}

	public void unequipAt(int pos) {
		equipments[pos] = Item.getNullItem();
	}

	/**
	 * 使用技能<br>
	 * 这里不允许npc使用不匹配的招架了
	 *
	 * @param id 技能id
	 */
	public Npc use(int id) {
		if(!Gmud.skill[id].checkable)
			return this;
		if (skillsckd[Gmud.skill[id].pos] == id) {
			skillsckd[Gmud.skill[id].pos] = -1;
		} else {
			skillsckd[Gmud.skill[id].pos] = id;
			if (Gmud.skill[id].pos <= 1) {
				skillsckd[4] = id;
			}
		}
		return this;
	}

	/**
	 * 是否装备了目标技能
	 *
	 * @param sklid 目标技能ID
	 */
	public boolean using(int sklid) {
		return Gmud.contains(skillsckd, sklid);
	}

	public void xiqi() {
		int t = Math.min(getFp(), getHp() - getSp());
		setFp(getFp() - t);
		setSp(getSp() + t);
	}

	/**
	 * @return 要获取的战斗数据。
	 */
	public NpcBattleData getBattleData() {
		return data;
	}

	public void setBattleData(NpcBattleData data) {
		this.data = data;
	}

	public int getFp() {
		return fp;
	}

	public void setFp(int fp) {
		this.fp = fp;
	}

	public int getMaxhp() {
		return getAttr(Room.ATTR_MAXHP);
	}


	public Npc applyTemplate(NpcModifier template){
		template.applyTo(this, 1);
		return this;
	}

	public Npc applyTemplate(NpcModifier template, float rate) {
		template.applyTo(this, rate);
		return this;
	}

	public Npc applyARandomTemplate(float rate, NpcModifier... template) {
		template[Gmud.rand.nextInt(template.length)].applyTo(this, rate);
		return this;
	}

	public int getTotalSkillLevel(){
		int sum = 0;
		for(int i : skills){
			sum += i;
		}
		return sum;
	}

	public int getSp() {
		return sp;
	}

	public void setSp(int sp) {
		this.sp = sp;
		Logger.v("Npc %s SP set : now %d / %d / %d", name, sp, hp, getAttr(Room.ATTR_MAXHP));
	}

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
		Logger.v("Npc %s HP set : now %d / %d / %d", name, sp, hp, getAttr(Room.ATTR_MAXHP));
	}
}
